package net.odtel.mailadmin.controller;

import java.util.Map;

import javax.validation.Valid;

import net.odtel.mailadmin.model.EmailAccount;
import net.odtel.mailadmin.services.EmailAccountService;
import net.odtel.mailadmin.services.EmailDomainService;
import net.odtel.mailadmin.util.MD5Crypt;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

@Controller
@SessionAttributes("emailAccount")
public class EmailAccountController {

	private static final Logger logger = LoggerFactory
			.getLogger(EmailAccountController.class);

	@Autowired
	private EmailAccountService emailAccountService;

	@Autowired
	private EmailDomainService emailDomainService;

	@RequestMapping(value = "/index")
	public String getList(Map<String, Object> map) {
		
		int indexPageId = 1;
		
		logger.info("Start compose index URL..." + indexPageId);

		int pagePrev = 0;
		int pageNext = 0;
		int pageFirst = 0;
		int pageLast = 0;

		int STRING_PER_PAGE = 5;

		int[] range = new int[2];

		int kPage = (int) Math.ceil((double) emailAccountService.count()
				/ STRING_PER_PAGE);

		logger.info("All Pages " + kPage + " count ="
				+ (double) emailAccountService.count() / STRING_PER_PAGE);

		if (kPage == 1) {
			map.put("emailAccountList", emailAccountService.findRange(range));
			map.put("emailAccount", new EmailAccount());
			map.put("emailDomainList", emailDomainService.getMap());
			map.put("pagePrev", pagePrev);
			map.put("pageNext", pageNext);
			map.put("pageFirst", pageFirst);
			map.put("pageLast", pageLast);
		}

		if (indexPageId > kPage) {
			indexPageId = kPage;
		}

		range[0] = (indexPageId - 1) * STRING_PER_PAGE;
		range[1] = range[0] + STRING_PER_PAGE;
		if (indexPageId < kPage) {
			pageNext = indexPageId + 1;
			pageLast = kPage;
		}

		if (indexPageId > 1) {
			pagePrev = indexPageId - 1;
			pageFirst = 1;
		}

		logger.info("All Pages " + kPage + " pagePrev ="
				+ pagePrev);

		
		map.put("emailAccountList", emailAccountService.findRange(range));
		map.put("emailDomainList", emailDomainService.getMap());
		map.put("pagePrev", pagePrev);
		map.put("pageNext", pageNext);
		map.put("pageFirst", pageFirst);
		map.put("pageLast", pageLast);

		return "emailAccount";

		
		
	}

	@RequestMapping("/")
	public String index() {
		return "redirect:/index";
	}

	@RequestMapping(value = "/index/{indexPageId}", method = RequestMethod.GET)
	public String viewPages(@PathVariable("indexPageId") int indexPageId,
			Map<String, Object> map) {
		
		logger.info("Start compose index URL..." + indexPageId);

		int pagePrev = 0;
		int pageNext = 0;
		int pageFirst = 0;
		int pageLast = 0;

		int STRING_PER_PAGE = 5;

		int[] range = new int[2];

		int kPage = (int) Math.ceil((double) emailAccountService.count()
				/ STRING_PER_PAGE);

		logger.info("All Pages " + kPage + " count ="
				+ (double) emailAccountService.count() / STRING_PER_PAGE);

		if (kPage == 1) {
			map.put("emailAccountList", emailAccountService.findRange(range));
			map.put("emailAccount", new EmailAccount());
			map.put("emailDomainList", emailDomainService.getMap());
			map.put("pagePrev", pagePrev);
			map.put("pageNext", pageNext);
			map.put("pageFirst", pageFirst);
			map.put("pageLast", pageLast);
		}

		if (indexPageId > kPage) {
			indexPageId = kPage;
		}

		range[0] = (indexPageId - 1) * STRING_PER_PAGE;
		range[1] = range[0] + STRING_PER_PAGE;
		if (indexPageId < kPage) {
			pageNext = indexPageId + 1;
			pageLast = kPage;
		}

		if (indexPageId > 1) {
			pagePrev = indexPageId - 1;
			pageFirst = 1;
		}

		logger.info("All Pages " + kPage + " pagePrev ="
				+ pagePrev);

		
		map.put("emailAccountList", emailAccountService.findRange(range));
		map.put("emailDomainList", emailDomainService.getMap());
		map.put("pagePrev", pagePrev);
		map.put("pageNext", pageNext);
		map.put("pageFirst", pageFirst);
		map.put("pageLast", pageLast);

		return "emailAccount";

	}

	/*
	 * Закомментировано 2012.07.13
	 * 
	 * @RequestMapping(value = "/edit/save", method = RequestMethod.POST) public
	 * String updateEmailAccount(
	 * 
	 * @ModelAttribute("emailAccount") EmailAccount emailAccount, BindingResult
	 * result) { emailAccountService.update(emailAccount); return
	 * ("redirect:/index"); }
	 */

	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public String addEmailAccount(Map<String, Object> map) {
		EmailAccount emailAccount = new EmailAccount();
		map.put("emailAccount", emailAccount);
		map.put("emailDomainList", emailDomainService.getMap());
		return ("addEmailAccount");
	}

	/*
	 * @RequestMapping(value = "/addErrors", method = RequestMethod.GET) public
	 * String addEmailAccountErrors (@Valid EmailAccount emailAccount, Errors
	 * errors, Map<String, Object> map){ //emailAccount.setPassword("");
	 * map.put("emailAccount", emailAccount); map.put("emailDomainList",
	 * emailDomainService.getMap()); map.put("errors", errors); return
	 * ("addEmailAccount"); }
	 */

	@RequestMapping(value = "/newEmailAccount", method = RequestMethod.POST)
	public ModelAndView newEmailAccount(
			@ModelAttribute("emailAccount") EmailAccount emailAccount,
			BindingResult result) {
		EmailAccountValidator validator = new EmailAccountValidator();

		validator.setEmailAccountService(emailAccountService);
		validator.validate(emailAccount, result);

		if (result.hasErrors()) {
			ModelAndView mav = new ModelAndView("addEmailAccount");
			mav.addObject("emailAccount", emailAccount);
			mav.addObject("emailDomainList", emailDomainService.getMap());
			mav.addAllObjects(result.getModel());
			logger.info("[INFO++] errors: " + result.getErrorCount() + " "
					+ result.toString());
			return mav;
		}
		logger.info("[INFO] errors: " + result.getErrorCount() + " "
				+ result.toString());

		emailAccount.setPassword(MD5Crypt.crypt(emailAccount.getPassword()));
		emailAccountService.save(emailAccount);
		ModelAndView mav = new ModelAndView("redirect:/index");
		return mav;
	}

	/**
	 * 
	 * @param emailAccount
	 * @param result
	 * @return
	 */
	@RequestMapping(value = "/updateEmailAccount", method = RequestMethod.POST)
	public ModelAndView updateEmailAccount(
			@ModelAttribute("emailAccount") EmailAccount emailAccount,
			BindingResult result) {

		EmailAccountUpdateValidator validator = new EmailAccountUpdateValidator();

		logger.info("[INFO] errors: " + result.toString());

		validator.setEmailAccountService(emailAccountService);
		validator.validate(emailAccount, result);

		if (result.hasErrors()) {
			ModelAndView mav = new ModelAndView("editEmailAccount");
			mav.addObject("emailAccount", emailAccount);
			mav.addObject("emailDomainList", emailDomainService.getMap());
			mav.addAllObjects(result.getModel());
			logger.info("[INFO] errors: " + result.getErrorCount() + " "
					+ result.toString());
			return mav;
		}

		emailAccount.setPassword(MD5Crypt.crypt(emailAccount.getPassword()));
		emailAccountService.update(emailAccount);
		ModelAndView mav = new ModelAndView("redirect:/index");
		return mav;
	}

	/*
	 * @RequestMapping(value = "/newEmailAccount", method = RequestMethod.POST)
	 * public String newEmailAccount(@ModelAttribute("emailAccount")
	 * EmailAccount emailAccount, BindingResult result) { EmailAccountValidator
	 * validator = new EmailAccountValidator();
	 * validator.setEmailAccountService(emailAccountService);
	 * validator.validate(emailAccount, result); if (result.hasErrors()) {
	 * logger.info("[INFO] errors: " + result.getErrorCount() + " " +
	 * result.toString()); return ("redirect:/addErrors"); }
	 * emailAccount.setPassword(MD5Crypt.crypt(emailAccount.getPassword()));
	 * emailAccountService.save(emailAccount); return ("redirect:/index"); }
	 */
	/*
	 * @RequestMapping(value = "/newEmailAccount", method = RequestMethod.POST)
	 * public String newEmailAccount(@Valid EmailAccount emailAccount,
	 * BindingResult result) {
	 * emailAccount.setPassword(MD5Crypt.crypt(emailAccount.getPassword()));
	 * 
	 * if (result.hasErrors()) { return ("redirect:/addErrors"); }
	 * emailAccountService.save(emailAccount); return ("redirect:/index"); }
	 */
	/*
	 * @Resource(name="emailAccountValidator") private EmailAccountValidator
	 * emailAccountValidator;
	 * 
	 * @InitBinder public void initBinder(WebDataBinder binder) {
	 * binder.setValidator(this.emailAccountValidator); }
	 */
	@InitBinder("EmailAccountValidator")
	protected void initBinder(WebDataBinder binder) {
		binder.setValidator(new EmailAccountValidator());
	}

	@RequestMapping(value = "/edit/{emailAccountId}", method = RequestMethod.GET)
	public String editContact(
			@ModelAttribute("emailAccount") EmailAccount emailAccount,
			@PathVariable("emailAccountId") Long emailAccountId,
			Map<String, Object> map) {
		System.out
				.println("TRACE ---------------------------------------------");
		System.out.println(emailAccount.getUsername());
		emailAccount = emailAccountService.findById(emailAccountId);
		map.put("emailPassword", emailAccount.getPassword());
		emailAccount.setPassword("");
		map.put("emailAccount", emailAccount);
		map.put("emailDomainList", emailDomainService.getMap());
		System.out.println(emailAccount.getUsername());
		return "editEmailAccount";
	}

	@RequestMapping("/delete/{emailAccountId}")
	public String deleteContact(
			@PathVariable("emailAccountId") Long emailAccountId) {
		emailAccountService.remove(emailAccountId);

		return "redirect:/index";
	}

}
